package com.zhongyouyun.admin.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhongyouyun.admin.mapper.UserMapper;
import com.zhongyouyun.admin.model.UserModel;
import com.zhongyouyun.config.RedisConfig;
import com.zhongyouyun.other.annotation.SysLogAnnotation;
import com.zhongyouyun.other.model.Result;
import com.zhongyouyun.other.model.TokenUtil;
import com.zhongyouyun.other.thread.UserSiteThread;
import com.zhongyouyun.utils.IPUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.NonNull;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RestController
@RequestMapping("/admin/login")
@Api(value = "登录controller", tags = {"登录接口"})
public class LoginController {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RedisConfig redisConfig;


    /**
     * 登录
     *
     * @param userModel 用户实体类
     * @return
     */
    @PostMapping("/ajaxLogin")
    @ResponseBody
    @ApiOperation(value = "登录", notes = "登录")
    @SysLogAnnotation(operModul = "系统管理>>登录", operType = "登录", operDesc = "登入后台管理平台")
    public Result submitLogin(@RequestBody UserModel userModel) throws Exception {
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        QueryWrapper<UserModel> userModelQueryWrapper = new QueryWrapper<UserModel>();
        userModelQueryWrapper.eq("user_name", userModel.getUserName());
        userModelQueryWrapper.eq("password", SecureUtil.md5(userModel.getPassword()));
        UserModel user = userMapper.selectOne(userModelQueryWrapper);
        if (ObjectUtil.isNotEmpty(user)) {
            if ("0".equals(user.getState())) {
                return Result.builder().message("账号已锁定").status(1).data(resultMap).build();
            } else {
                if (ObjectUtil.isNotNull(user)) {
                    Subject subject = SecurityUtils.getSubject();
                    String u_token = null;
                    if (ObjectUtil.isEmpty(subject) && ObjectUtil.isEmpty(subject.getSession().getId())) {
                        UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());
                        subject.login(token);
                        subject = SecurityUtils.getSubject();
                        u_token = TokenUtil.getToken(user.getUserName(), subject.getSession().getId().toString(), token.getHost());
                    } else {
                        if (ObjectUtil.isEmpty(redisConfig.get(subject.getSession().getId().toString()))) {
                            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());
                            subject.login(token);
                            subject = SecurityUtils.getSubject();
                            u_token = TokenUtil.getToken(user.getUserName(), subject.getSession().getId().toString(), token.getHost());
                        } else {
                            u_token = redisConfig.get(subject.getSession().getId().toString()).toString();
                        }
                    }
                    resultMap.put("user", user);
                    redisConfig.set(subject.getSession().getId().toString(), u_token, 60 * 60 * 60 * 2L);
                    userModel.setActivation("1");
                    userMapper.updateById(userModel);
                    resultMap.put("code", subject.getSession().getId().toString());
                    System.out.println(subject.getSession().getId().toString());
                    resultMap.put("token", u_token);
                    return Result.builder().message("登录成功").status(0).data(resultMap).build();
                } else {
                    return Result.builder().message("账号密码错误").status(1).data(resultMap).build();
                }
            }
        } else {
            return Result.builder().message("账号密码错误").status(1).data(resultMap).build();
        }


    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @RequestMapping(value = "/getUser", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "获取用户信息刷新token时间", notes = "获取用户信息刷新token时间")
    public Result getUser() {
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        Subject subject = SecurityUtils.getSubject();
        Object u = subject.getPrincipal();
        if (u instanceof UserModel) {
            UserModel user = (UserModel) subject.getPrincipal(); // 获取当前登录用户
            resultMap.put("user", user);
            String u_token = (String) redisConfig.get(subject.getSession().getId().toString());
            redisConfig.set(subject.getSession().getId().toString(), u_token, 60 * 60 * 60 * 2L);
            return Result.builder().message("获取成功").status(0).data(resultMap).build();
        }
        return Result.builder().message("获取成功").status(0).data(resultMap).build();
    }

    /**
     * 退出
     *
     * @return
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "退出", notes = "退出")
    public Result logout(HttpServletRequest request) {
        String ipAddr = IPUtils.getIpAdrress(request);
        Subject subject = SecurityUtils.getSubject();
        Object object = redisConfig.get(subject.getSession().getId().toString());
        Claims b = TokenUtil.getTokenBody(object.toString());
        String name = b.get("sub").toString();
        ExecutorService cachedThreadPool = Executors.newSingleThreadExecutor();
        cachedThreadPool.execute(new UserSiteThread(name, ipAddr));
        redisConfig.romove(subject.getSession().getId().toString());
        //注销
        subject.logout();
        return Result.builder().message("注销成功").status(0).build();
    }

    /**
     * 修改密码
     *
     * @return
     */
    @PostMapping(value = "/updetebyPassword")
    @ResponseBody
    @ApiOperation(value = "修改密码", notes = "修改密码")
    public Result updetebyPassword(@NonNull @ApiParam(value = "userId") @RequestParam(value = "userId", required = false) String userId, @NonNull @ApiParam(value = "oldPassWord") @RequestParam(value = "oldPassWord", required = false) String oldPassWord, @NonNull @ApiParam(value = "newPassWord") @RequestParam(value = "newPassWord", required = false) String newPassWord) {
        QueryWrapper<UserModel> userModelQueryWrapper = new QueryWrapper<UserModel>();
        userModelQueryWrapper.eq("id", userId);
        userModelQueryWrapper.eq("password", SecureUtil.md5(oldPassWord));
        UserModel user = userMapper.selectOne(userModelQueryWrapper);
        user.setPassword(SecureUtil.md5(newPassWord));
        int flag = userMapper.updateById(user);
        if (flag == 1) {
            return Result.builder().message("成功").status(0).build();
        } else {
            return Result.builder().message("成功").status(1).build();
        }
    }
}
